package com.vancouver.knows.ui.activity.citydiscount;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Point;
import android.location.Location;
import android.os.Bundle;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.maps.android.clustering.Cluster;
import com.google.maps.android.clustering.ClusterItem;
import com.google.maps.android.clustering.ClusterManager;
import com.google.maps.android.clustering.view.DefaultClusterRenderer;
import com.google.maps.android.ui.IconGenerator;
import com.pangu.service.ActionException;
import com.pangu.task.IResultReceiver;
import com.pangu.task.mark.ATaskMark;
import com.vancouver.knows.R;
import com.vancouver.knows.business.BusinessModule;
import com.vancouver.knows.business.bean.DiscountInfo;
import com.vancouver.knows.business.bean.MapItem;
import com.vancouver.knows.business.task.mark.HomeMapTaskMark;
import com.vancouver.knows.ui.base.BaseActivity;
import com.vancouver.knows.util.AppUtils;
import com.vancouver.knows.util.PhoConstants;

import java.util.ArrayList;
import java.util.List;

import butterknife.Bind;
import butterknife.OnClick;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;

/**
 * Created by chenxunlin01 on 2016/6/6.
 */
public class MapActivity extends BaseActivity implements OnMapReadyCallback, IResultReceiver,View.OnClickListener {

    private static final float ZOOM_LEVEL = 15.0f;
    private static final int RC_LOCATION = 489;

    private GoogleMap mGoogleMap;
    private BusinessModule bModule;
    private ClusterManager<MapItem> mClusterManager;
    private double centerLat;
    private double centerLng;
    private String filter = "all";

    @Bind(R.id.progress)
    ProgressBar progress;
    @Bind(R.id.filter)
    ImageView filterIcon;
    @Bind(R.id.toolbar)
    public Toolbar toolbar;
    @Bind(R.id.toobarTitle)
    public TextView toobarTitle;
    MapSelectWindow mapSelectWindow;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);
        toolbar.setTitle("");
        setSupportActionBar(toolbar);
        toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.back));
        toobarTitle.setText(R.string.map_title);

        bModule = imContext.getBusinessModule();
        SupportMapFragment mapFragment = SupportMapFragment.newInstance();
        mapFragment.getMapAsync(this);
        getSupportFragmentManager().beginTransaction().add(R.id.mapContent, mapFragment).commit();
        mapSelectWindow = new MapSelectWindow(this, this);

        if (getIntent() != null) {
            String initialFilter = getIntent().getStringExtra("filter");
            if (initialFilter != null) {
                filter = initialFilter;
                filterIcon.setImageResource(R.drawable.action_filter_filled);
            }
        }
    }

    @AfterPermissionGranted(RC_LOCATION)
    private void enableLocation(boolean enable) {
        String[] perms = {Manifest.permission.ACCESS_FINE_LOCATION};
        if (EasyPermissions.hasPermissions(this, perms)) {
            if (mGoogleMap != null) {
                this.mGoogleMap.setMyLocationEnabled(enable);
            }
        } else {
            EasyPermissions.requestPermissions(this, "Need location permissions.",
                    RC_LOCATION, perms);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == RC_LOCATION) {
            if (grantResults.length == 0) { // denied
                finish();
                return;
            }
        }
        // Forward results to EasyPermissions
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onResume() {
        super.onResume();
        enableLocation(true);
    }

    @Override
    protected void onPause() {
        super.onPause();
        enableLocation(false);

    }

    @Override
    public void onMapReady(GoogleMap map) {
        if (map != null) {
            mClusterManager = new ClusterManager<MapItem>(this, map);
            mClusterManager.setRenderer(new MapClusterRenderer(this, map, mClusterManager));
            mClusterManager.setOnClusterClickListener(new ClusterManager.OnClusterClickListener<MapItem>() {
                @Override
                public boolean onClusterClick(Cluster<MapItem> cluster) {
                    List<DiscountInfo> data = new ArrayList<DiscountInfo>();
                    for (MapItem mapItem : cluster.getItems()) {
                        data.add(mapItem.getDiscountInfo());
                    }
                    bModule.getCacheManager().setSelectMapDiscountList(data);
                    Intent intent = new Intent(MapActivity.this, MapListActivity.class);
                    startActivity(intent);
                    return true;
                }
            });
            mClusterManager.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MapItem>() {
                @Override
                public boolean onClusterItemClick(MapItem mapItem) {
                    Intent intent = new Intent(MapActivity.this,CityDiscountDetailActivity.class);
                    intent.putExtra("postId",mapItem.getDiscountInfo().getId());
                    startActivity(intent);
                    return true;
                }
            });


            this.mGoogleMap = map;
            enableLocation(true);
            this.mGoogleMap.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() {
                @Override
                public boolean onMyLocationButtonClick() {
                    if (imContext.latitude != 0 || imContext.longitude != 0) {
                        LatLng centerPoint = new LatLng(imContext.latitude, imContext.longitude);
                        mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(centerPoint, ZOOM_LEVEL));
                    }
                    return true;
                }
            });
            this.mGoogleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
                @Override
                public void onMyLocationChange(Location location) {
                    if (location != null) {
                        if (imContext.latitude == 0 && imContext.longitude == 0) {
                            //移动地图
                            LatLng centerPoint = new LatLng(location.getLatitude(), location.getLongitude());
                            mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(centerPoint, ZOOM_LEVEL));
                        }
                        //设置位置
                        imContext.latitude = location.getLatitude();
                        imContext.longitude = location.getLongitude();
                    }
                }
            });
            map.setOnCameraChangeListener(mClusterManager);
            map.setOnMarkerClickListener(mClusterManager);
            if (imContext.latitude != 0 || imContext.longitude != 0) {
                LatLng centerPoint = new LatLng(imContext.latitude, imContext.longitude);
                mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(centerPoint, ZOOM_LEVEL));
            }
        }
    }

    @Override
    public void receiveResult(ATaskMark taskMark, ActionException exception, Object trackerResult) {
        if (taskMark.getTaskStatus() == ATaskMark.HANDLE_ERROR || taskMark.getTaskStatus() == ATaskMark.HANDLE_OVER) {
            progress.setVisibility(View.GONE);
            if (taskMark.getTaskStatus() == ATaskMark.HANDLE_OVER) {
                //显示mark
                List<MapItem> mapItems = new ArrayList<>();
                List<DiscountInfo> discountInfoList = bModule.getCacheManager().getMapDiscountList();
                if (discountInfoList != null) {
                    for (DiscountInfo discountInfo : discountInfoList) {
                        MapItem mapItem = new MapItem(discountInfo.getBusinessLat(), discountInfo.getBusinessLng(),
                                discountInfo);
                        mapItems.add(mapItem);
                    }
                    mClusterManager.clearItems();
                    mClusterManager.addItems(mapItems);
                    mClusterManager.cluster();
                }
            }
        }
    }

    @Override
    public void subHandleMessage(Message msg) {
        switch(msg.what){
            case PhoConstants.ACTION_MAP_FETCH_CITYDISCOUNT:
                DisplayMetrics dm = getResources().getDisplayMetrics();
                int w = dm.widthPixels;
                int h = dm.heightPixels;
                LatLng leftTop = mGoogleMap.getProjection().fromScreenLocation(new Point(0, 0));
                LatLng rightBottom = mGoogleMap.getProjection().fromScreenLocation(new Point(w, h));
                HomeMapTaskMark taskMark = bModule.getTaskMarkPool().createHomeMapTaskMark();
                String userId = AppUtils.getUserId(bModule);
                bModule.getServiceWrapper().homeMap(MapActivity.this, taskMark, userId, centerLat,
                        centerLng, leftTop.latitude, rightBottom.latitude, leftTop.longitude,
                        rightBottom.longitude, filter);
                progress.setVisibility(View.VISIBLE);
                break;
        }
    }

    @OnClick(R.id.filter)
    public void onFilterClick(){
        mapSelectWindow.show();
    }

    @OnClick(R.id.dataList)
    public void onDatalistClick(){
        bModule.getCacheManager().setSelectMapDiscountList(bModule.getCacheManager().getMapDiscountList());
        Intent intent = new Intent(this,MapListActivity.class);
        startActivity(intent);
    }

    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.map_all:
                filter="all";
                filterIcon.setImageResource(R.drawable.action_filter);
                sendEmptyMessage(PhoConstants.ACTION_MAP_FETCH_CITYDISCOUNT,500);
                break;
            case R.id.map_food:
                filter="food";
                filterIcon.setImageResource(R.drawable.action_filter_filled);
                sendEmptyMessage(PhoConstants.ACTION_MAP_FETCH_CITYDISCOUNT,500);
                break;
            case R.id.map_other:
                filter="other_than_food";
                filterIcon.setImageResource(R.drawable.action_filter_filled);
                sendEmptyMessage(PhoConstants.ACTION_MAP_FETCH_CITYDISCOUNT,500);
                break;
        }
        mapSelectWindow.dismiss();
    }

    private class MapClusterRenderer extends DefaultClusterRenderer implements GoogleMap.OnCameraChangeListener {

        private final IconGenerator mIconGenerator = new IconGenerator(getApplicationContext());
        private final IconGenerator mClusterIconGenerator = new IconGenerator(getApplicationContext());

        public MapClusterRenderer(Context context, GoogleMap map, ClusterManager clusterManager) {
            super(context, map, clusterManager);

            TextView clusterTextView = new TextView(getApplicationContext());
            clusterTextView.setGravity(Gravity.CENTER);
            clusterTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
            clusterTextView.setTextColor(Color.WHITE);
            clusterTextView.setBackgroundResource(R.drawable.marker_cluster);
            clusterTextView.setId(R.id.text);
            mClusterIconGenerator.setBackground(null);
            mClusterIconGenerator.setContentView(clusterTextView);

            TextView singleClusterTextView = new TextView(getApplicationContext());
            singleClusterTextView.setGravity(Gravity.CENTER);
            singleClusterTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
            singleClusterTextView.setTextColor(Color.WHITE);
            singleClusterTextView.setBackgroundResource(R.drawable.marker_single);
            singleClusterTextView.setText("1");
            singleClusterTextView.setPadding(0, 0, 0, (int) getResources().getDimension(R.dimen.marker_padding));
            mIconGenerator.setBackground(null);
            mIconGenerator.setContentView(singleClusterTextView);

        }

        @Override
        public void onCameraChange(CameraPosition cameraPosition) {
            centerLat = cameraPosition.target.latitude;
            centerLng = cameraPosition.target.longitude;
            sendEmptyMessage(PhoConstants.ACTION_MAP_FETCH_CITYDISCOUNT,1500);
        }

        @Override
        protected void onBeforeClusterItemRendered(ClusterItem item, MarkerOptions markerOptions) {
            Bitmap icon = mIconGenerator.makeIcon();
            markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
        }

        @Override
        protected void onBeforeClusterRendered(Cluster cluster, MarkerOptions markerOptions) {
            int clusterSize = cluster.getSize();
            Bitmap icon = mClusterIconGenerator.makeIcon(String.valueOf(clusterSize));

            int size = icon.getWidth();
            if (clusterSize >= 5) {
                int scaledSize = (int) (size * 1.1);
                icon = Bitmap.createScaledBitmap(icon, scaledSize, scaledSize, true);
            } else if (clusterSize >= 10) {
                int scaledSize = (int) (size * 1.15);
                icon = Bitmap.createScaledBitmap(icon, scaledSize, scaledSize, true);
            } else if (clusterSize >= 20) {
                int scaledSize = (int) (size * 1.2);
                icon = Bitmap.createScaledBitmap(icon, scaledSize, scaledSize, true);
            } else if (clusterSize >= 50) {
                int scaledSize = (int) (size * 1.25);
                icon = Bitmap.createScaledBitmap(icon, scaledSize, scaledSize, true);
            } else if (clusterSize >= 100) {
                int scaledSize = (int) (size * 1.5);
                icon = Bitmap.createScaledBitmap(icon, scaledSize, scaledSize, true);
            } else if (clusterSize >= 200) {
                int scaledSize = (int) (size * 1.75);
                icon = Bitmap.createScaledBitmap(icon, scaledSize, scaledSize, true);
            } else if (clusterSize >= 500) {
                int scaledSize = (int) (size * 2.0);
                icon = Bitmap.createScaledBitmap(icon, scaledSize, scaledSize, true);
            } else if (clusterSize >= 1000) {
                int scaledSize = (int) (size * 2.25);
                icon = Bitmap.createScaledBitmap(icon, scaledSize, scaledSize, true);
            }

            markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
        }

        @Override
        protected boolean shouldRenderAsCluster(Cluster cluster) {
            return cluster.getSize() > 1;
        }
    }
}
